import React, { useState, useEffect, useRef } from 'react';
import { PropTypes } from 'prop-types';
import { useDispatch } from 'react-redux';
import { HashRouter as Router } from 'react-router-dom';
import { useQuery } from '@shell-ui/hooks';
import { BlankPage } from '@shell-ui/components';
import AppContent from './AppWrapper';
import { getAPI, getMenuList } from './utils';
import { actions } from './store';
import './style.less';

const App = ({ store, registedEvent }) => {
  const [auth, setAuth] = useState(false);

  const dispatch = useDispatch();
  const [query] = useQuery();

  const getMenu = () => {
    return query.get(getAPI('GET_GLOBAL_MENU'), {}, {
      loading: false,
      mock: getAPI('GET_GLOBAL_MENU', 'mock'),
      callback: ({ data = [] }) => {
        const menus = getMenuList(data);
        const newData = {
          apps: _.flatMapDeep(menus, menu => menu.children)
        };
        dispatch({
          type: getAPI('GET_GLOBAL_MENU', 'action'),
          payload: newData
        })
      }
    })
  };

  const [appService, setAppService] = useState({});
  const moduleRoutes = useRef([]);
  const [registed, setRegisted] = useState(false);

  const onRegisterApp = async (event) => {
    const { name, render, reducer } = _.get(event, 'detail', {});
    store.injectReducer(name, reducer);

    const routes = await render(dispatch);
    moduleRoutes.current = moduleRoutes.current.concat(routes);

    setAppService({
      ...appService,
      [name]: {
        routes,
        reducer
      }
    });
    setRegisted(true);
    dispatch(actions.setRegistedApp(name));
  };

  const initApp = async () => {
    if (registedEvent) onRegisterApp(registedEvent);

    Promise.all([
      getMenu()
    ]).then(([data = true]) => {
      setAuth(data);
    });
  };

  useEffect(() => {
    initApp();
    window.addEventListener('onmoduleload', onRegisterApp);
    return () => window.removeEventListener('onmoduleload', onRegisterApp);
  }, []);

  if (!auth) {
    return <BlankPage code={301} loading />
  }

  return (
    <React.Fragment>
      <div className="nav-header" />
      <Router>
        <AppContent routes={moduleRoutes.current} registed={registed} setRegisted={setRegisted} />
      </Router>
      <div className="nav-footer" />
    </React.Fragment>
  );
};

App.propTypes = {
  store: PropTypes.object,
  registedEvent: PropTypes.object
};

App.defaultProps = {
  store: {},
  registedEvent: undefined
}

export default App;
